package ru.ifmo.thesis.gp.configurations;

import org.jgap.Configuration;
import org.jgap.DefaultFitnessEvaluator;
import org.jgap.InvalidConfigurationException;
import org.jgap.NaturalSelector;
import org.jgap.event.EventManager;
import org.jgap.event.IEventManager;
import org.jgap.impl.ChromosomePool;
import org.jgap.impl.GABreeder;
import org.jgap.impl.StockRandomGenerator;
import org.jgap.impl.TournamentSelector;
import org.jgap.impl.WeightedRouletteSelector;

import ru.ifmo.thesis.gp.MyConfigurationOptions;

public abstract class BaseConfiguration extends Configuration implements Cloneable {

	private final int i;
	
	public BaseConfiguration(MyConfigurationOptions options, IEventManager eventManager) {
		this.i = 0;
	}
	
	protected void doSetup(MyConfigurationOptions options, IEventManager eventManager) {
		try {
			setBreeder(new GABreeder());
			setRandomGenerator(new StockRandomGenerator());
			setEventManager(eventManager);
			NaturalSelector selector = createNaturalSelector(options);

			setPreservFittestIndividual(true);
			
			addNaturalSelector(selector, true);
//			addNaturalSelector(selector, false);
			
			setMinimumPopSizePercent(options.getPopulationSizeGuaranteed());
			
			setSelectFromPrevGen(1);
			
			setKeepPopulationSizeConstant(false);
			setFitnessEvaluator(new DefaultFitnessEvaluator());
//			setChromosomePool(new ChromosomePool());
			
			setupGeneticOperators(options);
		} catch (InvalidConfigurationException e) {
			throw new RuntimeException(
					"Fatal error: MyConfiguration class could not use its "
							+ "own stock configuration values. This should never happen. "
							+ "Please report this as a bug to the JGAP team.");
		}

	}

	protected abstract void setupGeneticOperators(MyConfigurationOptions options) throws InvalidConfigurationException;

	protected abstract NaturalSelector createNaturalSelector(MyConfigurationOptions options) throws InvalidConfigurationException;

	protected NaturalSelector weightedRouletteSelector() throws InvalidConfigurationException {
		return new WeightedRouletteSelector(this);
	}
	
	protected NaturalSelector tournamentSelectot() throws InvalidConfigurationException {
		return new TournamentSelector(this, 2, 1);
	}
}
